library(tm)
library(tidytext)
library(tidyverse)
library(DT)
library(tidyverse)
library(tidytext)
library(DT)
library(scales)
library(wordcloud2)
library(gridExtra)
library(ngram)
library(shiny)
library(wordcloud)
library(knitr)
Is Technology Making Millennials More Happy Than Human Interation?
About a year ago Forbes Magazine published an article titled “Why Millennials are Lonely”. It claimed that “The second reason for millennial loneliness is the Internet makes it viral” effect. It emphasizes that “It’s not a coincidence that loneliness began to surge two years after Apple launched its first commercial personal computer and five years before Tim Berners-Lee invented the World Wide Web.” This is a narrative that is seen across major media organizations like New York Times and NPR. These mediums often use representations of millennials as people always on their phone with no touch with the outside world. It is also a commonly believed that, millennials don’t want relationships as pointed out by the Huffington Post, almost pointing at a lack of need of human touch by millennials.
But are millenials as lonely as they claim? Is technology the main cause this loneliness? Are millennials not attracted to human touch anymore? Let’s find out.
I looked through a database (happyDB) to identify what made people happy. I then selected a group of millennials(generation y), generation x and generation z as defined by the Pew Research Center. Genertion x as people between the ages of 38 and 53. Generation y as people between the ages of 22 and 37. And generation Z as people between the age of 1 and 21.
# Step 1 - Load the processed text data along with demographic information on contributors
# We use the processed data for our analysis and combine it with the demographic information available.
hm_data1 <- read_csv("../output/processed_moments.csv")
hm_data2 <- read_csv("../output/processed_moments.csv")
urlfile<-'https://raw.githubusercontent.com/rit-public/HappyDB/master/happydb/data/demographic.csv'
demo_data1 <- read_csv(urlfile)
demo_data2 <- read_csv(urlfile)
#print(hm_data)
# ### Combine both the data sets and keep the required columns for analysis
#
# #We select a subset of the data that satisfies specific row conditions.
# hm_data1 <- hm_data1 %>%
# inner_join(demo_data1, by = "wid") %>%
# select(wid,
# original_hm,
# gender,
# marital,
# parenthood,
# reflection_period,
# age,
# country,
# ground_truth_category,
# text) %>%
# mutate(count = sapply(hm_data1$text, wordcount)) %>%
# filter(gender %in% c("m", "f")) %>%
# filter(marital %in% c("single", "married")) %>%
# filter(parenthood %in% c("n", "y")) %>%
# filter(reflection_period %in% c("24h", "3m")) %>%
# mutate(reflection_period = fct_recode(reflection_period,
# months_3 = "3m", hours_24 = "24h"))
# dim(hm_data1)
hm_data2 <- hm_data2 %>%
inner_join(demo_data2, by = "wid") %>%
select(wid,
original_hm,
gender,
marital,
parenthood,
reflection_period,
age,
country,
ground_truth_category,
text) %>%
mutate(count = sapply(hm_data2$text, wordcount)) %>%
filter(gender %in% c("m", "f")) %>%
filter(marital %in% c("single", "married")) %>%
filter(parenthood %in% c("n", "y")) %>%
filter(reflection_period %in% c("24h", "3m")) %>%
mutate(reflection_period = fct_recode(reflection_period,
months_3 = "3m", hours_24 = "24h"))
#print(hm_data2)
#datatable(hm_data)
#names(hm_data)
#datatable(hm_data1)
datatable(hm_data2)
#Create bigrams using the text data
# hm_bigrams <- hm_data1 %>%
# filter(count != 1) %>%
# unnest_tokens(bigram, text, token = "ngrams", n = 2)
#
# bigram_counts <- hm_bigrams %>%
# separate(bigram, c("word1", "word2"), sep = " ") %>%
# count(word1, word2, sort = TRUE)
#Create bigrams using the text data
hm_bigrams2 <- hm_data2 %>%
filter(count != 1) %>%
unnest_tokens(bigram, text, token = "ngrams", n = 2)
bigram_counts2 <- hm_bigrams2 %>%
separate(bigram, c("word1", "word2"), sep = " ") %>%
count(word1, word2, sort = TRUE)
#Create a data set with non-millenials
hm_data2$age <- as.numeric(as.character(hm_data2$age))
generationZ<-hm_data2 %>%
filter(age>=1 & age<=21)
#print(generationZ)
generationY<-hm_data2 %>%
filter(age>=22 & age<=37)
#print(generationY)
generationX<-hm_data2 %>%
filter(age>=38 & age<=53)
#print(generationX)
# dim(generationX) 14560 11
# dim(generationY)70233 11
# dim(generationZ) 5540 11
# ### Create a data set with milennials only
# hm_data1$age <- as.numeric(as.character(hm_data1$age))
# millenials<-hm_data1 %>%
# filter(age>=21 & age<=37)
# # tech_related<-read_csv("Technology_Entertainment.csv")
# # people_related<-read_csv("people-dict.csv")
# print(millenials)
# #Create a data set with non-millenials
# hm_data2$age <- as.numeric(as.character(hm_data2$age))
# names(hm_data2)
# hm_data2[age<=20 & age>=30]
#
# # non_millenials<-hm_data2 %>%
# # filter(age<=20 & age>=30)
# # print(non_millenials)
# print(hm_data2)
# dim(hm_data2)
# #Create a bag of words using the text data
### Create a bag of words using the text data
bag_of_words1 <-generationX %>%
unnest_tokens(word, text)
word_count1 <- bag_of_words1 %>%
count(word, sort = TRUE)
bag_of_words2 <- generationY %>%
unnest_tokens(word, text)
word_count2 <- bag_of_words2 %>%
count(word, sort = TRUE)
bag_of_words3 <-generationZ %>%
unnest_tokens(word, text)
word_count3 <- bag_of_words3 %>%
count(word, sort = TRUE)
Genration X
set.seed(1234)
wordcloud(words = word_count1$word, freq = word_count1$n, min.freq = 1,
max.words=10000, random.order=FALSE, rot.per=0.35,
colors=brewer.pal(8, "Paired"), main="Generation X")

Genration Y
set.seed(1234)
wordcloud(words = word_count2$word, freq = word_count2$n, min.freq = 1,
max.words=10000, random.order=FALSE, rot.per=0.35,
colors=brewer.pal(8, "Dark2"), main="Generation Y")

Genration X
set.seed(1234)
wordcloud(words = word_count3$word, freq = word_count3$n, min.freq = 1,
max.words=10000, random.order=FALSE, rot.per=0.35,
colors=brewer.pal(8, "Set1") ,main="Generation Z")

As shown in the word cloud above, the most common source of happiness on those 24hours in the lives of millennials were their friends. Out of 72, 060 Millennials that answered the survey, over 8,000 of then included friends and family as their top reason for their happiness.
# install.packages("devtools")
library(devtools)
# install_github("easyGgplot2", "kassambara")
#dim(word_count)
?barplot
#barplot(head(sort(word_count,decreasing=TRUE), n = 10))
# data(word_count) # clarity is a good categorical variable
# with(word_count, barplot(rev(sort(table(n))[1:10])))
# counts <- table(word_count$n)[1:10]
# typeof(word_count)
# # #barplot(word_count)[1:10]
# # print(word_count)
# # pino2=melt(word_count,id.vars=c('word','n'))
# # ggplot(pino2,aes(x=factor(word),y=n))+geom_bar(stat='identity')
# df <- data.frame(matrix(unlist(word_count), nrow=16532, byrow=T))
# print(df)
# ggplot(df,aes(x=factor(word),y=n))+geom_bar(stat='identity')
#word_count2<-word_count[1:10]
#ggplot(word_count, aes(x=word, y=n))
# wordyu<-as.data.frame(word_count)
# ndjksbd<-wordyu[1:10]
# print(ndjksbd)
#word_count
# #ggplot(word_count, aes(x=word, y=n))
mod_word_count1<-head(word_count1, n=10)
mod_word_count2<-head(word_count2, n=10)
mod_word_count3<-head(word_count3, n=10)
#print(mod_word_count)
# barplot(mod_word_count)
library(easyGgplot2)
ggplot2.barplot(data=mod_word_count1, xName="word",yName='n',xtickLabelRotation=90,backgroundColor="lightyellow", fill='green',color="blue", ytitle="Frequency", xtitle="Words", mainTitle="Top 10 Words Used by Generation X")

ggplot2.barplot(data=mod_word_count2, xName="word",yName='n',xtickLabelRotation=90,backgroundColor="lightblue", fill='green',color="blue", ytitle="Frequency", xtitle="Words", mainTitle="Top 10 Words Used by Generation Y (Millenials)")

ggplot2.barplot(data=mod_word_count3, xName="word",yName='n',xtickLabelRotation=90,backgroundColor="lightpink", fill='green',color="blue", ytitle="Frequency", xtitle="Words", mainTitle="Top 10 Words Used by Generation Z")

library(easyGgplot2)
ggplot2.barplot(data=mod_word_count1, xName="word",yName='(n/14560)*100',xtickLabelRotation=90,backgroundColor="lightyellow", fill='green',color="blue", ytitle="Percentage", xtitle="Words", mainTitle="Top 10 Words Used by Generation X")

ggplot2.barplot(data=mod_word_count2, xName="word",yName='(n/70233)*100',xtickLabelRotation=90,backgroundColor="lightblue", fill='green',color="blue", ytitle="Percentage", xtitle="Words", mainTitle="Top 10 Words Used by Generation Y (Millenials)")

ggplot2.barplot(data=mod_word_count3, xName="word",yName='(n/5540)*100',xtickLabelRotation=90,backgroundColor="lightpink", fill='green',color="blue", ytitle="Percentage", xtitle="Words", mainTitle="Top 10 Words Used by Generation Z")

# #print(tech_related)
# #print(people_related)
#
# word_list = str_split(millenials$text, " ")
# words = unlist(word_list)
# people.matches = match(words, people_related)
# tech.matches = match(words, tech_related)
# # get the position of the matched term or NA
# # we just want a TRUE/FALSE
# people_matches = !is.na(people.matches)
# tech_matches = !is.na(tech.matches)
# # final score
# score1 = sum(people_matches)
# score2=sum(tech_matches)
# print(score1)
# print(score2)
LS0tCnRpdGxlOiAiUHJvamVjdCAxIgpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sKLS0tCi0tLQp0aXRsZTogIlIgTm90ZWJvb2siCmF1dGhvcjogIlp1bGVpbXkgQWxjYW50YXJhICh6Z2EyMTAyKSIKZGF0ZTogIjkvMTgvMjAxOCIKb3V0cHV0OgogIGh0bWxfZG9jdW1lbnQ6CiAgICBkZl9wcmludDogcGFnZWQKLS0tCgoKCmBgYHtyIGxvYWQgbGlicmFyaWVzLCB3YXJuaW5nPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQpsaWJyYXJ5KHRtKQpsaWJyYXJ5KHRpZHl0ZXh0KQpsaWJyYXJ5KHRpZHl2ZXJzZSkKbGlicmFyeShEVCkKbGlicmFyeSh0aWR5dmVyc2UpCmxpYnJhcnkodGlkeXRleHQpCmxpYnJhcnkoRFQpCmxpYnJhcnkoc2NhbGVzKQpsaWJyYXJ5KHdvcmRjbG91ZDIpCmxpYnJhcnkoZ3JpZEV4dHJhKQpsaWJyYXJ5KG5ncmFtKQpsaWJyYXJ5KHNoaW55KSAKbGlicmFyeSh3b3JkY2xvdWQpCmxpYnJhcnkoa25pdHIpCmBgYAoKIyMjSXMgVGVjaG5vbG9neSBNYWtpbmcgTWlsbGVubmlhbHMgTW9yZSBIYXBweSBUaGFuIEh1bWFuIEludGVyYXRpb24/CiAhW10oaGFwcHl0ZWNoLmpwZykKIAoKQWJvdXQgYSB5ZWFyIGFnbyBGb3JiZXMgTWFnYXppbmUgcHVibGlzaGVkIGFuIGFydGljbGUgdGl0bGVkIOKAnFdoeSBNaWxsZW5uaWFscyBhcmUgTG9uZWx5Ii4gIEl0IGNsYWltZWQgdGhhdCDigJxUaGUgc2Vjb25kIHJlYXNvbiBmb3IgbWlsbGVubmlhbCBsb25lbGluZXNzIGlzIHRoZSBJbnRlcm5ldCBtYWtlcyBpdCB2aXJhbOKAnSBlZmZlY3QuIEl0IGVtcGhhc2l6ZXMgdGhhdCDigJxJdOKAmXMgbm90IGEgY29pbmNpZGVuY2UgdGhhdCBsb25lbGluZXNzIGJlZ2FuIHRvIHN1cmdlIHR3byB5ZWFycyBhZnRlciBBcHBsZSBsYXVuY2hlZCBpdHMgZmlyc3QgY29tbWVyY2lhbCBwZXJzb25hbCBjb21wdXRlciBhbmQgZml2ZSB5ZWFycyBiZWZvcmUgVGltIEJlcm5lcnMtTGVlIGludmVudGVkIHRoZSBXb3JsZCBXaWRlIFdlYi7igJ0gIFRoaXMgaXMgYSBuYXJyYXRpdmUgdGhhdCBpcyBzZWVuIGFjcm9zcyBtYWpvciBtZWRpYSBvcmdhbml6YXRpb25zIGxpa2UgTmV3IFlvcmsgVGltZXMgYW5kIE5QUi4gVGhlc2UgbWVkaXVtcyBvZnRlbiB1c2UgcmVwcmVzZW50YXRpb25zIG9mIG1pbGxlbm5pYWxzIGFzIHBlb3BsZSBhbHdheXMgb24gdGhlaXIgcGhvbmUgd2l0aCBubyB0b3VjaCB3aXRoIHRoZSBvdXRzaWRlIHdvcmxkLiBJdCBpcyBhbHNvIGEgY29tbW9ubHkgYmVsaWV2ZWQgdGhhdCwgbWlsbGVubmlhbHMgZG9u4oCZdCB3YW50IHJlbGF0aW9uc2hpcHMgYXMgcG9pbnRlZCBvdXQgYnkgdGhlIEh1ZmZpbmd0b24gUG9zdCwgYWxtb3N0IHBvaW50aW5nIGF0IGEgbGFjayBvZiBuZWVkIG9mIGh1bWFuIHRvdWNoIGJ5IG1pbGxlbm5pYWxzLiAhW05ZVC1BcmUgWW91IDIxIHRvIDM3PyBZb3UgTWlnaHQgQmUgYSBNaWxsZW5uaWFsXShtaWxsZW5pYWwuanBnKSBCdXQgYXJlIG1pbGxlbmlhbHMgYXMgbG9uZWx5IGFzIHRoZXkgY2xhaW0/IElzIHRlY2hub2xvZ3kgdGhlIG1haW4gY2F1c2UgdGhpcyBsb25lbGluZXNzPyBBcmUgbWlsbGVubmlhbHMgbm90IGF0dHJhY3RlZCB0byBodW1hbiB0b3VjaCBhbnltb3JlPyBMZXTigJlzIGZpbmQgb3V0LiAKCkkgbG9va2VkIHRocm91Z2ggYSBkYXRhYmFzZSAoaGFwcHlEQikgdG8gaWRlbnRpZnkgd2hhdCBtYWRlIHBlb3BsZSBoYXBweS4gSSB0aGVuIHNlbGVjdGVkIGEgZ3JvdXAgb2YgbWlsbGVubmlhbHMoZ2VuZXJhdGlvbiB5KSwgZ2VuZXJhdGlvbiB4IGFuZCBnZW5lcmF0aW9uIHogYXMgZGVmaW5lZCBieSB0aGUgUGV3IFJlc2VhcmNoIENlbnRlci4gR2VuZXJ0aW9uIHggYXMgcGVvcGxlIGJldHdlZW4gdGhlIGFnZXMgb2YgMzggYW5kIDUzLiBHZW5lcmF0aW9uIHkgYXMgcGVvcGxlIGJldHdlZW4gdGhlIGFnZXMgb2YgMjIgYW5kIDM3LiBBbmQgZ2VuZXJhdGlvbiBaIGFzIHBlb3BsZSBiZXR3ZWVuIHRoZSBhZ2Ugb2YgMSBhbmQgMjEuIAoKYGBge3IgbG9hZCBkYXRhLCB3YXJuaW5nPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQojIFN0ZXAgMSAtIExvYWQgdGhlIHByb2Nlc3NlZCB0ZXh0IGRhdGEgYWxvbmcgd2l0aCBkZW1vZ3JhcGhpYyBpbmZvcm1hdGlvbiBvbiBjb250cmlidXRvcnMKCiMgV2UgdXNlIHRoZSBwcm9jZXNzZWQgZGF0YSBmb3Igb3VyIGFuYWx5c2lzIGFuZCBjb21iaW5lIGl0IHdpdGggdGhlIGRlbW9ncmFwaGljIGluZm9ybWF0aW9uIGF2YWlsYWJsZS4KaG1fZGF0YTEgPC0gcmVhZF9jc3YoIi4uL291dHB1dC9wcm9jZXNzZWRfbW9tZW50cy5jc3YiKQpobV9kYXRhMiA8LSByZWFkX2NzdigiLi4vb3V0cHV0L3Byb2Nlc3NlZF9tb21lbnRzLmNzdiIpCnVybGZpbGU8LSdodHRwczovL3Jhdy5naXRodWJ1c2VyY29udGVudC5jb20vcml0LXB1YmxpYy9IYXBweURCL21hc3Rlci9oYXBweWRiL2RhdGEvZGVtb2dyYXBoaWMuY3N2JwpkZW1vX2RhdGExIDwtIHJlYWRfY3N2KHVybGZpbGUpCmRlbW9fZGF0YTIgPC0gcmVhZF9jc3YodXJsZmlsZSkKI3ByaW50KGhtX2RhdGEpCmBgYAoKCgpgYGB7ciwgd2FybmluZz1GQUxTRSwgbWVzc2FnZT1GQUxTRX0KIyAjIyMgQ29tYmluZSBib3RoIHRoZSBkYXRhIHNldHMgYW5kIGtlZXAgdGhlIHJlcXVpcmVkIGNvbHVtbnMgZm9yIGFuYWx5c2lzCiMgCiMgI1dlIHNlbGVjdCBhIHN1YnNldCBvZiB0aGUgZGF0YSB0aGF0IHNhdGlzZmllcyBzcGVjaWZpYyByb3cgY29uZGl0aW9ucy4KIyBobV9kYXRhMSA8LSBobV9kYXRhMSAlPiUKIyAgIGlubmVyX2pvaW4oZGVtb19kYXRhMSwgYnkgPSAid2lkIikgJT4lCiMgICBzZWxlY3Qod2lkLAojICAgICAgICAgIG9yaWdpbmFsX2htLAojICAgICAgICAgIGdlbmRlciwgCiMgICAgICAgICAgbWFyaXRhbCwgCiMgICAgICAgICAgcGFyZW50aG9vZCwKIyAgICAgICAgICByZWZsZWN0aW9uX3BlcmlvZCwKIyAgICAgICAgICBhZ2UsIAojICAgICAgICAgIGNvdW50cnksIAojICAgICAgICAgIGdyb3VuZF90cnV0aF9jYXRlZ29yeSwgCiMgICAgICAgICAgdGV4dCkgJT4lCiMgICBtdXRhdGUoY291bnQgPSBzYXBwbHkoaG1fZGF0YTEkdGV4dCwgd29yZGNvdW50KSkgJT4lCiMgICBmaWx0ZXIoZ2VuZGVyICVpbiUgYygibSIsICJmIikpICU+JQojICAgZmlsdGVyKG1hcml0YWwgJWluJSBjKCJzaW5nbGUiLCAibWFycmllZCIpKSAlPiUKIyAgIGZpbHRlcihwYXJlbnRob29kICVpbiUgYygibiIsICJ5IikpICU+JQojICAgZmlsdGVyKHJlZmxlY3Rpb25fcGVyaW9kICVpbiUgYygiMjRoIiwgIjNtIikpICU+JQojICAgbXV0YXRlKHJlZmxlY3Rpb25fcGVyaW9kID0gZmN0X3JlY29kZShyZWZsZWN0aW9uX3BlcmlvZCwgCiMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1vbnRoc18zID0gIjNtIiwgaG91cnNfMjQgPSAiMjRoIikpCiMgZGltKGhtX2RhdGExKQpgYGAKCmBgYHtyIGNvbWJpbmluZyBkYXRhLCB3YXJuaW5nPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQoKaG1fZGF0YTIgPC0gaG1fZGF0YTIgJT4lCiAgaW5uZXJfam9pbihkZW1vX2RhdGEyLCBieSA9ICJ3aWQiKSAlPiUKICBzZWxlY3Qod2lkLAogICAgICAgICBvcmlnaW5hbF9obSwKICAgICAgICAgZ2VuZGVyLCAKICAgICAgICAgbWFyaXRhbCwgCiAgICAgICAgIHBhcmVudGhvb2QsCiAgICAgICAgIHJlZmxlY3Rpb25fcGVyaW9kLAogICAgICAgICBhZ2UsIAogICAgICAgICBjb3VudHJ5LCAKICAgICAgICAgZ3JvdW5kX3RydXRoX2NhdGVnb3J5LCAKICAgICAgICAgdGV4dCkgJT4lCiAgbXV0YXRlKGNvdW50ID0gc2FwcGx5KGhtX2RhdGEyJHRleHQsIHdvcmRjb3VudCkpICU+JQogIGZpbHRlcihnZW5kZXIgJWluJSBjKCJtIiwgImYiKSkgJT4lCiAgZmlsdGVyKG1hcml0YWwgJWluJSBjKCJzaW5nbGUiLCAibWFycmllZCIpKSAlPiUKICBmaWx0ZXIocGFyZW50aG9vZCAlaW4lIGMoIm4iLCAieSIpKSAlPiUKICBmaWx0ZXIocmVmbGVjdGlvbl9wZXJpb2QgJWluJSBjKCIyNGgiLCAiM20iKSkgJT4lCiAgbXV0YXRlKHJlZmxlY3Rpb25fcGVyaW9kID0gZmN0X3JlY29kZShyZWZsZWN0aW9uX3BlcmlvZCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtb250aHNfMyA9ICIzbSIsIGhvdXJzXzI0ID0gIjI0aCIpKQojcHJpbnQoaG1fZGF0YTIpCmBgYAoKCgpgYGB7ciB3YXJuaW5nPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQojZGF0YXRhYmxlKGhtX2RhdGEpCiNuYW1lcyhobV9kYXRhKQojZGF0YXRhYmxlKGhtX2RhdGExKQpkYXRhdGFibGUoaG1fZGF0YTIpCmBgYAoKCgoKYGBge3IsIHdhcm5pbmc9RkFMU0UsIG1lc3NhZ2U9RkFMU0V9CiNDcmVhdGUgYmlncmFtcyB1c2luZyB0aGUgdGV4dCBkYXRhCiMgaG1fYmlncmFtcyA8LSBobV9kYXRhMSAlPiUKIyAgIGZpbHRlcihjb3VudCAhPSAxKSAlPiUKIyAgIHVubmVzdF90b2tlbnMoYmlncmFtLCB0ZXh0LCB0b2tlbiA9ICJuZ3JhbXMiLCBuID0gMikKIyAKIyBiaWdyYW1fY291bnRzIDwtIGhtX2JpZ3JhbXMgJT4lCiMgICBzZXBhcmF0ZShiaWdyYW0sIGMoIndvcmQxIiwgIndvcmQyIiksIHNlcCA9ICIgIikgJT4lCiMgICBjb3VudCh3b3JkMSwgd29yZDIsIHNvcnQgPSBUUlVFKQpgYGAKCmBgYHtyIGJpZ3JhbSwgd2FybmluZz1GQUxTRSwgbWVzc2FnZT1GQUxTRX0KI0NyZWF0ZSBiaWdyYW1zIHVzaW5nIHRoZSB0ZXh0IGRhdGEKaG1fYmlncmFtczIgPC0gaG1fZGF0YTIgJT4lCiAgZmlsdGVyKGNvdW50ICE9IDEpICU+JQogIHVubmVzdF90b2tlbnMoYmlncmFtLCB0ZXh0LCB0b2tlbiA9ICJuZ3JhbXMiLCBuID0gMikKCmJpZ3JhbV9jb3VudHMyIDwtIGhtX2JpZ3JhbXMyICU+JQogIHNlcGFyYXRlKGJpZ3JhbSwgYygid29yZDEiLCAid29yZDIiKSwgc2VwID0gIiAiKSAlPiUKICBjb3VudCh3b3JkMSwgd29yZDIsIHNvcnQgPSBUUlVFKQpgYGAKCmBgYHtyLCB3YXJuaW5nPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQojQ3JlYXRlIGEgZGF0YSBzZXQgd2l0aCBub24tbWlsbGVuaWFscwpobV9kYXRhMiRhZ2UgPC0gYXMubnVtZXJpYyhhcy5jaGFyYWN0ZXIoaG1fZGF0YTIkYWdlKSkKCmdlbmVyYXRpb25aPC1obV9kYXRhMiAlPiUgCiAgZmlsdGVyKGFnZT49MSAmIGFnZTw9MjEpIAojcHJpbnQoZ2VuZXJhdGlvblopCgpnZW5lcmF0aW9uWTwtaG1fZGF0YTIgJT4lIAogIGZpbHRlcihhZ2U+PTIyICYgYWdlPD0zNykKI3ByaW50KGdlbmVyYXRpb25ZKQoKZ2VuZXJhdGlvblg8LWhtX2RhdGEyICU+JSAKICBmaWx0ZXIoYWdlPj0zOCAmIGFnZTw9NTMpIAojcHJpbnQoZ2VuZXJhdGlvblgpCiMgZGltKGdlbmVyYXRpb25YKSAxNDU2MCAgICAxMQojIGRpbShnZW5lcmF0aW9uWSk3MDIzMyAgICAxMQojIGRpbShnZW5lcmF0aW9uWikgNTU0MCAgIDExCmBgYAoKYGBge3IsIGZpZy5hbGlnbj0iY2VudGVyIn0KIyAjIyMgQ3JlYXRlIGEgZGF0YSBzZXQgd2l0aCBtaWxlbm5pYWxzIG9ubHkKIyBobV9kYXRhMSRhZ2UgPC0gYXMubnVtZXJpYyhhcy5jaGFyYWN0ZXIoaG1fZGF0YTEkYWdlKSkKIyBtaWxsZW5pYWxzPC1obV9kYXRhMSAlPiUgCiMgICBmaWx0ZXIoYWdlPj0yMSAmIGFnZTw9MzcpCiMgIyB0ZWNoX3JlbGF0ZWQ8LXJlYWRfY3N2KCJUZWNobm9sb2d5X0VudGVydGFpbm1lbnQuY3N2IikKIyAjIHBlb3BsZV9yZWxhdGVkPC1yZWFkX2NzdigicGVvcGxlLWRpY3QuY3N2IikKIyBwcmludChtaWxsZW5pYWxzKQoKCmBgYAoKCgpgYGB7ciwgd2FybmluZz1GQUxTRSwgbWVzc2FnZT1GQUxTRX0KIyAjQ3JlYXRlIGEgZGF0YSBzZXQgd2l0aCBub24tbWlsbGVuaWFscwojIGhtX2RhdGEyJGFnZSA8LSBhcy5udW1lcmljKGFzLmNoYXJhY3RlcihobV9kYXRhMiRhZ2UpKQojIG5hbWVzKGhtX2RhdGEyKQojIGhtX2RhdGEyW2FnZTw9MjAgJiBhZ2U+PTMwXQojIAojICMgbm9uX21pbGxlbmlhbHM8LWhtX2RhdGEyICU+JSAKIyAjICAgZmlsdGVyKGFnZTw9MjAgJiBhZ2U+PTMwKSAKIyAjIHByaW50KG5vbl9taWxsZW5pYWxzKQojIHByaW50KGhtX2RhdGEyKQojIGRpbShobV9kYXRhMikKYGBgCgpgYGB7ciAsIHdhcm5pbmc9RkFMU0UsIG1lc3NhZ2U9RkFMU0V9CgojICNDcmVhdGUgYSBiYWcgb2Ygd29yZHMgdXNpbmcgdGhlIHRleHQgZGF0YQoKYGBgCgpgYGB7ciBiYWcgb2Ygd29yZHMsIHdhcm5pbmc9RkFMU0UsIG1lc3NhZ2U9RkFMU0V9CiMjIyBDcmVhdGUgYSBiYWcgb2Ygd29yZHMgdXNpbmcgdGhlIHRleHQgZGF0YQoKYmFnX29mX3dvcmRzMSA8LWdlbmVyYXRpb25YICU+JQogIHVubmVzdF90b2tlbnMod29yZCwgdGV4dCkKCndvcmRfY291bnQxIDwtIGJhZ19vZl93b3JkczEgJT4lCiAgY291bnQod29yZCwgc29ydCA9IFRSVUUpCgpiYWdfb2Zfd29yZHMyIDwtICBnZW5lcmF0aW9uWSAlPiUKICB1bm5lc3RfdG9rZW5zKHdvcmQsIHRleHQpCgp3b3JkX2NvdW50MiA8LSBiYWdfb2Zfd29yZHMyICU+JQogIGNvdW50KHdvcmQsIHNvcnQgPSBUUlVFKQoKYmFnX29mX3dvcmRzMyA8LWdlbmVyYXRpb25aICU+JQogIHVubmVzdF90b2tlbnMod29yZCwgdGV4dCkKCndvcmRfY291bnQzIDwtIGJhZ19vZl93b3JkczMgJT4lCiAgY291bnQod29yZCwgc29ydCA9IFRSVUUpCmBgYAojIyBHZW5yYXRpb24gWCMjCmBgYHtyLCB3YXJuaW5nPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQpzZXQuc2VlZCgxMjM0KQp3b3JkY2xvdWQod29yZHMgPSB3b3JkX2NvdW50MSR3b3JkLCBmcmVxID0gd29yZF9jb3VudDEkbiwgbWluLmZyZXEgPSAxLAogICAgICAgICAgbWF4LndvcmRzPTEwMDAwLCByYW5kb20ub3JkZXI9RkFMU0UsIHJvdC5wZXI9MC4zNSwgCiAgICAgICAgICBjb2xvcnM9YnJld2VyLnBhbCg4LCAiUGFpcmVkIiksIG1haW49IkdlbmVyYXRpb24gWCIpCmBgYAoKIyMgR2VucmF0aW9uIFkjIwpgYGB7ciwgd2FybmluZz1GQUxTRSwgbWVzc2FnZT1GQUxTRX0Kc2V0LnNlZWQoMTIzNCkKd29yZGNsb3VkKHdvcmRzID0gd29yZF9jb3VudDIkd29yZCwgZnJlcSA9IHdvcmRfY291bnQyJG4sIG1pbi5mcmVxID0gMSwKICAgICAgICAgIG1heC53b3Jkcz0xMDAwMCwgcmFuZG9tLm9yZGVyPUZBTFNFLCByb3QucGVyPTAuMzUsIAogICAgICAgICAgY29sb3JzPWJyZXdlci5wYWwoOCwgIkRhcmsyIiksIG1haW49IkdlbmVyYXRpb24gWSIpCmBgYAojIyBHZW5yYXRpb24gWCMjICAKYGBge3IsIHdhcm5pbmc9RkFMU0UsIG1lc3NhZ2U9RkFMU0V9CnNldC5zZWVkKDEyMzQpCndvcmRjbG91ZCh3b3JkcyA9IHdvcmRfY291bnQzJHdvcmQsIGZyZXEgPSB3b3JkX2NvdW50MyRuLCBtaW4uZnJlcSA9IDEsCiAgICAgICAgICBtYXgud29yZHM9MTAwMDAsIHJhbmRvbS5vcmRlcj1GQUxTRSwgcm90LnBlcj0wLjM1LCAKICAgICAgICAgIGNvbG9ycz1icmV3ZXIucGFsKDgsICJTZXQxIikgLG1haW49IkdlbmVyYXRpb24gWiIpCgpgYGAKQXMgc2hvd24gaW4gdGhlIHdvcmQgY2xvdWQgYWJvdmUsIHRoZSBtb3N0IGNvbW1vbiBzb3VyY2Ugb2YgaGFwcGluZXNzIG9uIHRob3NlIDI0aG91cnMgaW4gdGhlIGxpdmVzIG9mIG1pbGxlbm5pYWxzIHdlcmUgdGhlaXIgZnJpZW5kcy4gT3V0IG9mIDcyLCAwNjAgTWlsbGVubmlhbHMgdGhhdCBhbnN3ZXJlZCB0aGUgc3VydmV5LCBvdmVyIDgsMDAwIG9mIHRoZW4gaW5jbHVkZWQgZnJpZW5kcyBhbmQgZmFtaWx5IGFzIHRoZWlyIHRvcCByZWFzb24gZm9yIHRoZWlyIGhhcHBpbmVzcy4gCmBgYHtyLCB3YXJuaW5nPUZBTFNFfQojIGluc3RhbGwucGFja2FnZXMoImRldnRvb2xzIikKbGlicmFyeShkZXZ0b29scykKIyBpbnN0YWxsX2dpdGh1YigiZWFzeUdncGxvdDIiLCAia2Fzc2FtYmFyYSIpCgojZGltKHdvcmRfY291bnQpCj9iYXJwbG90CiNiYXJwbG90KGhlYWQoc29ydCh3b3JkX2NvdW50LGRlY3JlYXNpbmc9VFJVRSksIG4gPSAxMCkpCgojIGRhdGEod29yZF9jb3VudCkgIyBjbGFyaXR5IGlzIGEgZ29vZCBjYXRlZ29yaWNhbCB2YXJpYWJsZQojIHdpdGgod29yZF9jb3VudCwgYmFycGxvdChyZXYoc29ydCh0YWJsZShuKSlbMToxMF0pKSkKIyBjb3VudHMgPC0gdGFibGUod29yZF9jb3VudCRuKVsxOjEwXQojIHR5cGVvZih3b3JkX2NvdW50KQojICMgI2JhcnBsb3Qod29yZF9jb3VudClbMToxMF0KIyAjIHByaW50KHdvcmRfY291bnQpCiMgIyBwaW5vMj1tZWx0KHdvcmRfY291bnQsaWQudmFycz1jKCd3b3JkJywnbicpKQojICMgZ2dwbG90KHBpbm8yLGFlcyh4PWZhY3Rvcih3b3JkKSx5PW4pKStnZW9tX2JhcihzdGF0PSdpZGVudGl0eScpCiMgZGYgPC0gZGF0YS5mcmFtZShtYXRyaXgodW5saXN0KHdvcmRfY291bnQpLCBucm93PTE2NTMyLCBieXJvdz1UKSkKIyBwcmludChkZikKIyBnZ3Bsb3QoZGYsYWVzKHg9ZmFjdG9yKHdvcmQpLHk9bikpK2dlb21fYmFyKHN0YXQ9J2lkZW50aXR5JykKI3dvcmRfY291bnQyPC13b3JkX2NvdW50WzE6MTBdCiNnZ3Bsb3Qod29yZF9jb3VudCwgYWVzKHg9d29yZCwgeT1uKSkKIyB3b3JkeXU8LWFzLmRhdGEuZnJhbWUod29yZF9jb3VudCkKIyBuZGprc2JkPC13b3JkeXVbMToxMF0KIyBwcmludChuZGprc2JkKQojd29yZF9jb3VudAojICNnZ3Bsb3Qod29yZF9jb3VudCwgYWVzKHg9d29yZCwgeT1uKSkKbW9kX3dvcmRfY291bnQxPC1oZWFkKHdvcmRfY291bnQxLCBuPTEwKQptb2Rfd29yZF9jb3VudDI8LWhlYWQod29yZF9jb3VudDIsIG49MTApCm1vZF93b3JkX2NvdW50MzwtaGVhZCh3b3JkX2NvdW50Mywgbj0xMCkKICNwcmludChtb2Rfd29yZF9jb3VudCkKIyBiYXJwbG90KG1vZF93b3JkX2NvdW50KQpsaWJyYXJ5KGVhc3lHZ3Bsb3QyKQpnZ3Bsb3QyLmJhcnBsb3QoZGF0YT1tb2Rfd29yZF9jb3VudDEsIHhOYW1lPSJ3b3JkIix5TmFtZT0nbicseHRpY2tMYWJlbFJvdGF0aW9uPTkwLGJhY2tncm91bmRDb2xvcj0ibGlnaHR5ZWxsb3ciLCBmaWxsPSdncmVlbicsY29sb3I9ImJsdWUiLCB5dGl0bGU9IkZyZXF1ZW5jeSIsIHh0aXRsZT0iV29yZHMiLCBtYWluVGl0bGU9IlRvcCAxMCBXb3JkcyBVc2VkIGJ5IEdlbmVyYXRpb24gWCIpCgpnZ3Bsb3QyLmJhcnBsb3QoZGF0YT1tb2Rfd29yZF9jb3VudDIsIHhOYW1lPSJ3b3JkIix5TmFtZT0nbicseHRpY2tMYWJlbFJvdGF0aW9uPTkwLGJhY2tncm91bmRDb2xvcj0ibGlnaHRibHVlIiwgZmlsbD0nZ3JlZW4nLGNvbG9yPSJibHVlIiwgeXRpdGxlPSJGcmVxdWVuY3kiLCB4dGl0bGU9IldvcmRzIiwgbWFpblRpdGxlPSJUb3AgMTAgV29yZHMgVXNlZCBieSBHZW5lcmF0aW9uIFkgKE1pbGxlbmlhbHMpIikKCmdncGxvdDIuYmFycGxvdChkYXRhPW1vZF93b3JkX2NvdW50MywgeE5hbWU9IndvcmQiLHlOYW1lPSduJyx4dGlja0xhYmVsUm90YXRpb249OTAsYmFja2dyb3VuZENvbG9yPSJsaWdodHBpbmsiLCBmaWxsPSdncmVlbicsY29sb3I9ImJsdWUiLCB5dGl0bGU9IkZyZXF1ZW5jeSIsIHh0aXRsZT0iV29yZHMiLCBtYWluVGl0bGU9IlRvcCAxMCBXb3JkcyBVc2VkIGJ5IEdlbmVyYXRpb24gWiIpCgpgYGAKICAKCmBgYHtyLCB3YXJuaW5nPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQpsaWJyYXJ5KGVhc3lHZ3Bsb3QyKQpnZ3Bsb3QyLmJhcnBsb3QoZGF0YT1tb2Rfd29yZF9jb3VudDEsIHhOYW1lPSJ3b3JkIix5TmFtZT0nKG4vMTQ1NjApKjEwMCcseHRpY2tMYWJlbFJvdGF0aW9uPTkwLGJhY2tncm91bmRDb2xvcj0ibGlnaHR5ZWxsb3ciLCBmaWxsPSdncmVlbicsY29sb3I9ImJsdWUiLCB5dGl0bGU9IlBlcmNlbnRhZ2UiLCB4dGl0bGU9IldvcmRzIiwgbWFpblRpdGxlPSJUb3AgMTAgV29yZHMgVXNlZCBieSBHZW5lcmF0aW9uIFgiKQoKZ2dwbG90Mi5iYXJwbG90KGRhdGE9bW9kX3dvcmRfY291bnQyLCB4TmFtZT0id29yZCIseU5hbWU9JyhuLzcwMjMzKSoxMDAnLHh0aWNrTGFiZWxSb3RhdGlvbj05MCxiYWNrZ3JvdW5kQ29sb3I9ImxpZ2h0Ymx1ZSIsIGZpbGw9J2dyZWVuJyxjb2xvcj0iYmx1ZSIsIHl0aXRsZT0iUGVyY2VudGFnZSIsIHh0aXRsZT0iV29yZHMiLCBtYWluVGl0bGU9IlRvcCAxMCBXb3JkcyBVc2VkIGJ5IEdlbmVyYXRpb24gWSAoTWlsbGVuaWFscykiKQoKZ2dwbG90Mi5iYXJwbG90KGRhdGE9bW9kX3dvcmRfY291bnQzLCB4TmFtZT0id29yZCIseU5hbWU9JyhuLzU1NDApKjEwMCcseHRpY2tMYWJlbFJvdGF0aW9uPTkwLGJhY2tncm91bmRDb2xvcj0ibGlnaHRwaW5rIiwgZmlsbD0nZ3JlZW4nLGNvbG9yPSJibHVlIiwgeXRpdGxlPSJQZXJjZW50YWdlIiwgeHRpdGxlPSJXb3JkcyIsIG1haW5UaXRsZT0iVG9wIDEwIFdvcmRzIFVzZWQgYnkgR2VuZXJhdGlvbiBaIikKIyAjcHJpbnQodGVjaF9yZWxhdGVkKQojICNwcmludChwZW9wbGVfcmVsYXRlZCkKIyAKIyAgIHdvcmRfbGlzdCA9IHN0cl9zcGxpdChtaWxsZW5pYWxzJHRleHQsICIgIikKIyAgICAgICAgICAgICAgICAgICAgd29yZHMgPSB1bmxpc3Qod29yZF9saXN0KQojICAgICAgICAgICAgICAgICAgICBwZW9wbGUubWF0Y2hlcyA9IG1hdGNoKHdvcmRzLCBwZW9wbGVfcmVsYXRlZCkKIyAgICAgICAgICAgICAgICAgICAgdGVjaC5tYXRjaGVzID0gbWF0Y2god29yZHMsIHRlY2hfcmVsYXRlZCkKIyAgICAgICAgICAgICAgICAgICAgIyBnZXQgdGhlIHBvc2l0aW9uIG9mIHRoZSBtYXRjaGVkIHRlcm0gb3IgTkEKIyAgICAgICAgICAgICAgICAgICAgIyB3ZSBqdXN0IHdhbnQgYSBUUlVFL0ZBTFNFCiMgICAgICAgICAgICAgICAgICAgIHBlb3BsZV9tYXRjaGVzID0gIWlzLm5hKHBlb3BsZS5tYXRjaGVzKQojICAgICAgICAgICAgICAgICAgICB0ZWNoX21hdGNoZXMgPSAhaXMubmEodGVjaC5tYXRjaGVzKQojICAgICAgICAgICAgICAgICAgICAjIGZpbmFsIHNjb3JlCiMgICAgICAgICAgICAgICAgICAgICBzY29yZTEgPSBzdW0ocGVvcGxlX21hdGNoZXMpIAojICAgICAgICAgICAgICAgICAgICAgc2NvcmUyPXN1bSh0ZWNoX21hdGNoZXMpCiMgICAgICAgICAgICAgICAgICAgICBwcmludChzY29yZTEpCiMgICAgICAgICAgICAgICAgICAgICBwcmludChzY29yZTIpCgpgYGAKCg==